package com.rabiitmq.spring;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
public class Provider {

    @Autowired
    private AmqpTemplate amqpTemplate;

    @GetMapping("/send")
    public void testSend() throws InterruptedException {
        String msg = "hello, Spring boot amqp";
        this.amqpTemplate.convertAndSend("spring.test.exchange","a.b", msg);
        // 等待10秒后再结束
        Thread.sleep(10000);
    }

    //--------------------------- 手动ack ---------------------------------
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @GetMapping("/sendack")
    public void testSendAck() throws InterruptedException {
        /**
         * @Description 消息发送确认
         * <p>
         * ConfirmCallback  只确认消息是否正确到达 Exchange 中
         * ReturnCallback   消息没有正确到达队列时触发回调，如果正确到达队列不执行
         * <p>
         * 1. 如果消息没有到exchange,则confirm回调,ack=false
         * 2. 如果消息到达exchange,则confirm回调,ack=true
         * 3. exchange到queue成功,则不回调return
         * 4. exchange到queue失败,则回调return
         */
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                /*
                 ack 表示消息是否到达了交换机，交换机是否确认收到消息
                 cause 存储的是没有到达交换机的原因
                */
                if(!ack){
                    System.out.println("如果没有到达交换机，根据需要写你的业务代码");
                    log.info("消息发送失败:,{}", cause);
                }else{
                    log.info("消息发送成功:,{}", correlationData);
                }
            }
        });
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            @Override
            public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                log.info("消息主体:,{}", message);
                log.info("应答码:,{}", replyCode);
                log.info("描述:,{}", replyText);
                log.info("消息使用的交换器 exchange :,{}", exchange);
                log.info("消息使用的路由键 routing :,{}", routingKey);
            }
        });
        String msg = "hello, Spring boot amqp";
        rabbitTemplate.convertAndSend("spring.test.exchange","a.b", msg);
        // 等待10秒后再结束
        Thread.sleep(10000);
    }
}
